﻿using JNPF.Basics.Logic;
using JNPF.Basics.Models;
using JNPF.Basics.Models.Extend.Dtos.Email;
using JNPF.Utils;
using JNPF.Utils.Controller;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace JNPF.Basics.Controller
{
    /// <summary>
    /// 邮件收发
    /// 版 本：V3.0.0
    /// 版 权：引迈信息技术有限公司（https://www.jnpfsoft.com）
    /// 作 者：JNPF开发平台组
    /// 日 期：2017.11.28
    /// </summary>
    [Route("api/Extend/[controller]")]
    public class EmailController : BaseApiController
    {
        private EmailBll emailBll = new EmailBll();

        #region GET
        /// <summary>
        /// (带分页)获取邮件列表(收件箱、标星件、草稿箱、已发送)
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResponseResult> GetReceiveList([FromQuery] EmailListQuery input)
        {
            var pageInput = input.MapTo<PageInput>();
            pageInput.queryJson = JsonHelper.ToJson(new { input.startTime, input.endTime });
            var data = await GetEmailResultByType(input.type, pageInput);
            return Success(data);
        }

        /// <summary>
        /// 信息（配置）
        /// </summary>
        /// <returns></returns>
        [HttpGet("Config")]
        public async Task<ResponseResult> GetConfigInfo()
        {
            var userId = UserProvider.Instance.Get().UserId;
            var data = await emailBll.GetConfigInfo(userId);
            var output = new EmailConfigInfoOutput();
            if (data != null)
            {
                output = data.MapTo<EmailConfigInfoOutput>();
                output.emailSsl = data.Ssl;
            }
            return Success(output);
        }

        /// <summary>
        /// 信息（收件/发件）
        /// </summary>
        /// <param name="id">主键值</param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<ResponseResult> GetInfo(string id)
        {
            var output = new EmailInfoOutput();
            var data = await emailBll.GetInfo(id);
            var jobj = JsonHelper.ToObject(data.ToJson());
            if (jobj.ContainsKey("Read"))
            {
                var entity = data.MapTo<EmailReceiveEntity>();
                output = entity.MapTo<EmailInfoOutput>();
                output.recipient = entity.MAccount;
                output.fdate = entity.Date;
            }
            else
            {
                var entity = data.MapTo<EmailSendEntity>();
                output = entity.MapTo<EmailInfoOutput>();
                output.recipient = entity.To;
            }
            return Success(output);
        }
        #endregion

        #region POST
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id">主键值</param>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task<ResponseResult> Delete(string id)
        {
            await emailBll.Delete(id);
            return Success("删除成功");
        }

        /// <summary>
        /// 设置已读邮件
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPut("{id}/Actions/Read")]
        public async Task<ResponseResult> ReceiveRead(string id)
        {
            await emailBll.ReceiveRead(id, 1);
            return Success("操作成功");
        }

        /// <summary>
        /// 设置未读邮件
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPut("{id}/Actions/Unread")]
        public async Task<ResponseResult> ReceiveUnread(string id)
        {
            await emailBll.ReceiveRead(id, 0);
            return Success("操作成功");
        }

        /// <summary>
        /// 设置星标邮件
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPut("{id}/Actions/Star")]
        public async Task<ResponseResult> ReceiveYesStarred(string id)
        {
            await emailBll.ReceiveStarred(id, 1);
            return Success("操作成功");
        }

        /// <summary>
        /// 设置取消星标
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPut("{id}/Actions/Unstar ")]
        public async Task<ResponseResult> ReceiveNoStarred(string id)
        {
            await emailBll.ReceiveStarred(id, 0);
            return Success("操作成功");
        }

        /// <summary>
        /// 收邮件
        /// </summary>
        /// <returns></returns>
        [HttpPost("Receive")]
        public async Task<ResponseResult> Receive()
        {
            var userId = UserProvider.Instance.Get().UserId;
            var mailConfig = await emailBll.GetConfigInfo(userId);
            if (mailConfig != null)
            {
                if (MailHelper.CheckConnected(new MailAccount
                {
                    Account = mailConfig.Account,
                    Password = mailConfig.Password,
                    POP3Host = mailConfig.POP3Host,
                    POP3Port = mailConfig.POP3Port.ToInt(),
                    SMTPHost = mailConfig.SMTPHost,
                    SMTPPort = mailConfig.SMTPPort.ToInt()
                }))
                {
                    var mailCount = await emailBll.Receive(userId, mailConfig);
                    return Success("操作成功", mailCount);
                }
                else
                {
                    return Error("账户认证错误");
                }
            }
            else
            {
                return Error("你还没有设置邮件的帐户");
            }
        }

        /// <summary>
        /// 存草稿
        /// </summary>
        /// <param name="input">对象实体</param>
        /// <returns></returns>
        [HttpPost("Actions/SaveDraft")]
        [IgnoreCheckScript]
        public async Task<ResponseResult> SaveDraft([FromBody] EmailActionsSaveDraftInput input)
        {
            var entity = input.MapTo<EmailSendEntity>();
            entity.BodyText = WebHelper.HtmlEncode(entity.BodyText);
            entity.To = input.recipient;
            entity.Sender = ConfigurationKey.ErrorReportTo;
            await emailBll.SaveDraft(entity);
            return Success("保存成功");
        }

        /// <summary>
        /// 发邮件
        /// </summary>
        /// <param name="input">对象实体</param>
        /// <returns></returns>
        [HttpPost]
        [IgnoreCheckScript]
        public async Task<ResponseResult> SaveSent([FromBody] EmailSendInput input)
        {
            var entity = input.MapTo<EmailSendEntity>();
            var userId = UserProvider.Instance.Get().UserId;
            var mailConfig = await emailBll.GetConfigInfo(userId);
            if (mailConfig != null)
            {
                entity.BodyText = WebHelper.HtmlEncode(entity.BodyText);
                entity.To = input.recipient;
                entity.Sender = ConfigurationKey.ErrorReportTo;
                await emailBll.SaveSent(entity, userId, mailConfig);
                return Success("发送成功");
            }
            else
            {
                return Error("你还没有设置邮件的帐户");
            }
        }

        /// <summary>
        /// 保存邮箱配置
        /// </summary>
        /// <param name="input">对象实体</param>
        /// <returns></returns>
        [HttpPut("Config")]
        public async Task<ResponseResult> SaveConfig([FromBody] EmailConfigUpInput input)
        {
            var entity = input.MapTo<EmailConfigEntity>();
            entity.Ssl = input.emailSsl;
            entity.CreatorUserId = UserProvider.Instance.Get().UserId;
            await emailBll.SaveConfig(entity);
            return Success("保存成功");
        }

        /// <summary>
        /// 邮箱账户密码验证
        /// </summary>
        /// <param name="input">对象实体</param>
        /// <returns></returns>
        [HttpPost("Config/Actions/CheckMail")]
        public ResponseResult CheckLogin([FromBody] EmailConfigActionsCheckMailInput input)
        {
            var entity = input.MapTo<EmailConfigEntity>();
            if (MailHelper.CheckConnected(new MailAccount
            {
                Account = entity.Account,
                Password = entity.Password,
                POP3Host = entity.POP3Host,
                POP3Port = entity.POP3Port.ToInt(),
                SMTPHost = entity.SMTPHost,
                SMTPPort = entity.SMTPPort.ToInt()
            }))
            {
                return Success("验证成功");
            }
            else
            {
                return Error("账户认证错误");
            }
        }

        /// <summary>
        /// 下载附件
        /// </summary>
        /// <param name="fileModel">文件对象</param>
        [HttpPost("Download")]
        public void Download(FileModel fileModel)
        {
            var filePath = ConfigurationKey.EmailFilePath + fileModel.FileId;
            if (FileHelper.Exists(filePath))
            {
                FileHelper.DownloadFile(filePath, fileModel.FileName);
            }
        }
        #endregion

        #region Method
        /// <summary>
        /// 根据类型获取不同的邮箱列表
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="input">参数</param>
        /// <returns></returns>
        private async Task<PageResult> GetEmailResultByType(string type, PageInput input)
        {
            var output = new PageResult();
            var list = new List<EmailListOutput>();
            switch (type)
            {
                case "inBox"://收件箱
                    var dataReceive = await emailBll.GetReceiveList(input);
                    dataReceive.list.ForEach(x => list.Add(new EmailListOutput()
                    {
                        attachment = x.Attachment,
                        creatorTime = x.CreatorTime,
                        fdate = x.Date,
                        id = x.Id,
                        isRead = x.Read,
                        sender = x.SenderName,
                        starred = x.Starred,
                        subject = x.Subject
                    }));
                    output.list = list;
                    output.pagination = dataReceive.pagination;
                    return output;
                case "star"://标星件
                    var dataStarred = await emailBll.GetStarredList(input);
                    dataStarred.list.ForEach(x => list.Add(new EmailListOutput()
                    {
                        attachment = x.Attachment,
                        creatorTime = x.CreatorTime,
                        fdate = x.Date,
                        id = x.Id,
                        isRead = x.Read,
                        sender = x.SenderName,
                        starred = x.Starred,
                        subject = x.Subject
                    }));
                    output.list = list;
                    output.pagination = dataStarred.pagination;
                    return output;
                case "draft"://草稿箱
                    var dataDraft = await emailBll.GetDraftList(input);
                    dataDraft.list.ForEach(x => list.Add(new EmailListOutput()
                    {
                        attachment = x.Attachment,
                        creatorTime = x.CreatorTime,
                        id = x.Id,
                        recipient = x.To,
                        subject = x.Subject
                    }));
                    output.list = list;
                    output.pagination = dataDraft.pagination;
                    return output;
                case "sent"://已发送
                    var dataSent = await emailBll.GetSentList(input);
                    dataSent.list.ForEach(x => list.Add(new EmailListOutput()
                    {
                        attachment = x.Attachment,
                        creatorTime = x.CreatorTime,
                        id = x.Id,
                        recipient = x.To,
                        subject = x.Subject
                    }));
                    output.list = list;
                    output.pagination = dataSent.pagination;
                    return output;
                default:
                    return output;
            }
        }
        #endregion
    }
}
